// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <memory>

#include <pollux/dwio/common/buffered_input.h>
#include <pollux/dwio/common/options.h>
#include <pollux/dwio/common/reader.h>

namespace kumo::pollux::dwio::common {
    /**
     * Reader factory interface.
     *
     * Implement this interface to provide a factory of readers
     * for a particular file format. Factory objects should be
     * registered using registerReaderFactory method to become
     * available for connectors. Only a single reader factory
     * per file format is allowed.
     */
    class ReaderFactory {
    public:
        /**
         * Constructor.
         * @param format File format this factory is designated to.
         */
        explicit ReaderFactory(FileFormat format) : format_(format) {
        }

        virtual ~ReaderFactory() = default;

        /**
         * Get the file format ths factory is designated to.
         */
        FileFormat fileFormat() const {
            return format_;
        }

        /**
         * Create a reader object.
         * @param stream input stream
         * @param options reader options
         * @return reader object
         */
        virtual std::unique_ptr<Reader> createReader(
            std::unique_ptr<BufferedInput>,
            const ReaderOptions &options) = 0;

    private:
        const FileFormat format_;
    };

    /**
     * Register a reader factory. Only a single factory can be registered
     * for each file format. An attempt to register multiple factories for
     * a single file format would cause a filure.
     * @return true
     */
    bool registerReaderFactory(std::shared_ptr<ReaderFactory> factory);

    /**
     * Unregister a reader factory for a specified file format.
     * @return true for unregistered factory and false for a
     * missing factory for the specfified format.
     */
    bool unregisterReaderFactory(FileFormat format);

    /**
     * Get reader factory object for a specified file format. Results in
     * a failure if there is no registered factory for this format.
     * @return ReaderFactory object
     */
    std::shared_ptr<ReaderFactory> getReaderFactory(FileFormat format);
} // namespace kumo::pollux::dwio::common
